#include "include/NativeRenderer.h"
#include "include/NativePTAMSystem.h"
#include <string.h>
#include <jni.h>

NativePTAMSystem* ptamSys = NULL;
NativeRenderer* nr = NULL;

bool ofpInitialized = false;

extern "C"
{

	/*
	 *
	 * Native PTAM System Interface
	 *
	 */

	JNIEXPORT jint JNICALL Java_com_sarc_vision_PTAMSystem_NativeInit(JNIEnv* env, jobject)
	{
		if (ptamSys != NULL)
		{
			delete ptamSys;
		}
		ptamSys = new NativePTAMSystem();
		return PTAM_STATE_INITIALIZED_WITHOUT_CAM_PARAM;
	}

	JNIEXPORT jint JNICALL Java_com_sarc_vision_PTAMSystem_NativeInitWithCamParam(JNIEnv* env, jobject, jlong addrCameraMatrixMat, jlong addrDistortionCoefMat)
	{
		if (ptamSys != NULL)
		{
			delete ptamSys;
		}
		ptamSys = new NativePTAMSystem(addrCameraMatrixMat, addrDistortionCoefMat);
		return PTAM_STATE_INITIALIZED_WITH_CAM_PARAM;
	}

	JNIEXPORT jint JNICALL Java_com_sarc_vision_PTAMSystem_NativeRelease(JNIEnv* env, jobject)
	{
		if (ptamSys != NULL)
		{
			delete ptamSys;
		}
		ptamSys = NULL;
		return PTAM_STATE_NOT_INITIALIZED;
	}

	JNIEXPORT jint JNICALL Java_com_sarc_vision_PTAMSystem_NativeProcessNewFrame(JNIEnv* env, jobject, jlong addrGray, jlong addrFrameToDraw)
	{
		if (ptamSys != NULL)
		{
			return ptamSys->processFrame(addrGray, addrFrameToDraw);
		}
		else return PTAM_STATE_NOT_INITIALIZED;
	}

	JNIEXPORT jint JNICALL Java_com_sarc_vision_PTAMSystem_NativeGetCameraMatrix(JNIEnv* env, jobject, jlong addrCameraMatrixMat, jlong addrDistortionCoefMat)
	{
		if (ptamSys != NULL)
		{
			bool success =  ptamSys->getCameraMatrix(addrCameraMatrixMat, addrDistortionCoefMat);
			if (success)
				return PTAM_STATE_CALIBRATION_COMPLETED;
			else
				return PTAM_STATE_NOT_CALIBRATED;
		}
		else return PTAM_STATE_NOT_INITIALIZED;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_vision_PTAMSystem_NativeGetExtrinsics(JNIEnv* env, jobject, jlong addrMatRv, jlong addrMatTv)
	{
		if (ptamSys != NULL)
		{
			return ptamSys->getExtrinsics(addrMatRv, addrMatTv);
		}
		else return false;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_vision_PTAMSystem_NativeGetUV(JNIEnv* env, jobject, jlong addrMatUV, jlong addrMatVV)
	{
		if (ptamSys != NULL)
		{
			return ptamSys->getExtrinsics(addrMatUV, addrMatVV);
		}
		else return false;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_vision_PTAMSystem_NativeCaptureOnNextFrame(JNIEnv* env, jobject)
	{
		if (ptamSys != NULL)
		{
			ptamSys->captureOnNextFrame();
			return true;
		}
		else return false;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_vision_PTAMSystem_NativeResetOnNextFrame(JNIEnv* env, jobject)
	{
		if (ptamSys != NULL)
		{
			ptamSys->resetOnNextFrame();
			return true;
		}
		else return false;
	}

	JNIEXPORT jstring JNICALL Java_com_sarc_vision_PTAMSystem_NativeGetOutputString(JNIEnv* env, jobject)
	{
		if (ptamSys != NULL)
		{
			return env->NewStringUTF(ptamSys->getOutputString().data());
		}
		else return env->NewStringUTF("");
	}

	/*
	 *
	 * Native Renderer Interface
	 *
	 */

	JNIEXPORT jboolean JNICALL Java_com_sarc_games_TouchBalls_NativeInit(JNIEnv* env, jobject)
	{
		__android_log_print(ANDROID_LOG_INFO, "jni_part: ", "NativeInit");
		if (nr != NULL)
		{
			delete nr;
		}
		nr = new NativeRenderer();
		return true;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_games_TouchBalls_NativeRelease(JNIEnv* env, jobject)
	{
		bool success = false;
		if (nr != NULL)
		{
			delete nr;
			nr = NULL;
			success = true;
		}
		return success;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_games_TouchBalls_NativeSetUp(JNIEnv* env, jobject)
	{
		bool success = false;
		if (nr != NULL)
		{
			nr->SetUp();
			success = true;
		}
		return success;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_games_TouchBalls_NativeCleanUp(JNIEnv* env, jobject)
	{
		bool success = false;
		if (nr != NULL)
		{
			nr->CleanUp();
			success = true;
		}
		return success;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_games_TouchBalls_NativeRenderMat(JNIEnv* env, jobject, jlong addrMat, jfloat x, jfloat y, jfloat z)
	{
		bool success = false;
		if (nr != NULL)
		{
			nr->RenderMat(addrMat, x, y, z);
			success = true;
		}
		return success;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_games_TouchBalls_NativeUpdateLocation(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat z)
	{
		bool success = false;
		if (nr != NULL)
		{
			nr->UpdateLocation(x, y, z);
			success = true;
		}
		return success;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_games_TouchBalls_NativeGLInit(JNIEnv* env, jobject)
	{
		bool success = false;
		if (nr != NULL)
		{
			nr->GLInit();
			success = true;
		}
		return success;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_games_TouchBalls_NativeResize(JNIEnv* env, jobject, jint width, jint height)
	{
		bool success = false;
		if (nr != NULL)
		{
			nr->Resize(width, height);
			success = true;
		}
		return success;
	}

	JNIEXPORT jboolean JNICALL Java_com_sarc_games_TouchBalls_NativeStep(JNIEnv* env, jobject)
	{

		bool success = false;
		if (nr != NULL)
		{
			nr->Step();
			success = true;
		}
		return success;
	}

}
